package com.iot.auth.config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.iot.auth.endpoint.SecurityAuthenticationEntryPoint;
import com.iot.auth.filter.SecurityAuthorizationFilter;
import com.iot.auth.filter.SecurityUsernamePasswordAuthenticationFilter;
import com.iot.auth.handler.SecurityLogoutSuccessHandler;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;

/**
 * 认证服务器配置
 * 
 * @author love
 */
@Primary
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

	@Qualifier("securityUserDetailsService")
	private final UserDetailsService securityUserDetailsService;

	private final StringRedisTemplate redisTemplate;

	private final SecurityLogoutSuccessHandler logoutSuccessHandler;

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(securityUserDetailsService).passwordEncoder(new BCryptPasswordEncoder());
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {

		http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 使用 JWT，
//				.and()
//				.httpBasic()
				.and().formLogin().loginProcessingUrl("/oauth/token")
				.and()
				.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll() //任何用户任意方法可以访问/**
				.antMatchers("/oauth/**").permitAll() 
				/* .mvcMatchers("login","token") */
                .anyRequest().authenticated()
                .and()
				// 开启登录
				.formLogin()
				.and().logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler).and()
				.addFilterBefore(
						new SecurityUsernamePasswordAuthenticationFilter(authenticationManager(), redisTemplate),
						UsernamePasswordAuthenticationFilter.class)
				.addFilterBefore(new SecurityAuthorizationFilter(authenticationManager(), redisTemplate),
						UsernamePasswordAuthenticationFilter.class)
				.exceptionHandling().and().exceptionHandling()
				.authenticationEntryPoint(new SecurityAuthenticationEntryPoint()).and()
				// 允许跨域请求
				.cors().disable();
	}

	@Bean
	@Override
	@SneakyThrows
	public AuthenticationManager authenticationManagerBean() {
		return super.authenticationManagerBean();
	}
	
    /**
     * 注入PasswordEncoder
     * @return
     */
    @Bean
    public PasswordEncoder encoder() {
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        return encoder;
    }
    
	

}
